package com.dave.gd.core.rule.execute.impl;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.springframework.stereotype.Service;

import com.dave.gd.common.util.StringUtils;
import com.dave.gd.common.util.spring.ApplicationContextUtil;
import com.dave.gd.core.base.entity.impl.AbstractBaseEntity;
import com.dave.gd.core.context.SessionContext;
import com.dave.gd.core.rule.ERuleMode;
import com.dave.gd.core.rule.RuleEvent;
import com.dave.gd.core.rule.execute.IRuleExecute;
import com.dave.gd.core.rule.execute.IRuleMgrExecute;
import com.dave.gd.core.rule.intf.IRlmRuleIntf;
import com.dave.gd.core.rule.intf.IRlmRuleIntfService;

/**
 * Created by linzq on 2014/11/17.
 */
@Service("ruleMgrExecute")
public class RuleMgrExecuteImpl implements IRuleMgrExecute {
    @Override
    public boolean execute(AbstractBaseEntity entt, String methodName) {
        Object[] args = new Object[0];
        RuleEvent ruleEvent = new RuleEvent(entt, args, methodName);
        return execute(entt, methodName, ruleEvent);
    }
    
    @Override
    public boolean execute(AbstractBaseEntity entt, String methodName, Object... params) {
        RuleEvent ruleEvent = new RuleEvent(entt, params, methodName);
        return execute(entt, methodName, ruleEvent);
    }
    
    private boolean execute(AbstractBaseEntity entt, String methodName, RuleEvent ruleEvent) {
        // 如果全局关闭规则， 不做规则校验直接返回
        ERuleMode rm = SessionContext.getRuleMode();
        if (rm != null && rm == ERuleMode.DISABLE) {
            return true;
        }
        
        // 根据规则配置装载规则列表 根据entt过滤出规则
        // 调研 规则管理服务 提取规则列表 ---
        IRlmRuleIntfService service = ApplicationContextUtil.getBean("rlmRuleService");
        ///List<IRlmRuleIntf> rules = service.getClassRelRules();
        List<IRlmRuleIntf> rules = service.getClassRelRules(entt.getModelClass(), methodName, entt.getOrderServiceOffers());
        // 排序后再执行。
        if (rules.size() > 1) {
            sortRlmRules(rules);
        }
        
        boolean result = true;
        for (IRlmRuleIntf rule : rules) {
            IRuleExecute exec = rule.getExecutor();
            boolean curResult;
            if (StringUtils.isNullOrEmpty(rule.getRuleExcecuteMeth())) {
                curResult = exec.execute(rule, ruleEvent);
            } else {
                curResult = exec.execute(rule.getRuleExcecuteMeth(), rule, ruleEvent);
            }
        }
        
        SessionContext.collectWarnResults(entt.getWarnResults());
        return true;
    }
    
    /**
     * 增则规则执行前按照ruleSeq排序的功能，ruleSeq小的优先执行.
     *
     * @param list
     *            排序规则列表
     * @author zhoupc
     *         2011-9-28 zhoupc
     */
    static public void sortRlmRules(List<IRlmRuleIntf> list) {
        Comparator c = new Comparator<IRlmRuleIntf>() {
            public int compare(IRlmRuleIntf r1, IRlmRuleIntf r2) {
                Long l1 = r1.getRuleSeq();
                Long l2 = r2.getRuleSeq();
                if (l1 == null && l2 == null) {
                    return -1;
                } else if (l1 == null) {
                    return 1;
                } else if (l2 == null) {
                    return -1;
                } else {
                    return l1.intValue() - l2.intValue();
                }
            }
        };
        Collections.sort(list, c);
    }
}
